iT邦幫忙

2021 iThome 鐵人賽

DAY 8
1
自我挑戰組

從C到JS的同步非同步探索系列 第 8

[Day 8] .Net Task 底層(1)

  • 分享至 

  • xImage
  •  

前言

昨天聊過 Task.WhenAll , 得知其底層就是等待多個 Task 完成的機制, 那 Task 到底是甚麼呢 ?

Task類別代表不會傳回值,而且通常會以非同步方式執行的單一作業。 Task 物件是工作架構 非同步模式 的其中一個核心元件,第一次是在 .NET Framework 4 中引進。 由於物件所執行的工作 Task 通常會線上程集區執行緒上以非同步方式執行,而不是在主應用程式執行緒上同步執行,因此您可以使用 Status 屬性以及 IsCanceled 、 IsCompleted 和 IsFaulted 屬性來判斷工作的狀態。 最常見的情況是使用 lambda 運算式來指定工作要執行的工作。

以上是微軟文件裡的說法, 這段敘述其實並不能說服我, 所以我打算從另一個角度是著揭開它的神秘面紗。 接下來對 Task 的探索可能會更為凌亂, 但我想探索底層就如同瞎子摸象, 每一次都摸一點點, 換個角度再摸一點點, 當累積足夠, 就可以真正了解大象的模樣。

從繼承的父輩開始

public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable

可以看見繼承自三種物件, 其中 IAsyncResult 放了一些變數, 比較簡單之後遇到順口提即可。

IDisposable 是釋放資源相關, 跟同步非同步沒太大關連。

我們把焦點放在 IThreadPoolWorkItem , Task 其實簡單點說, 就是 IThreadPoolWorkItem 的封裝。

進入 IThreadPoolWorkItem 可以看到, 他就是一個介面, 讓人可以把 something 送入 TP ( threadPool )


// Interface to something that can be queued to the TP.  This is implemented by
// QueueUserWorkItemCallback, Task, and potentially other internal types.
// For example, SemaphoreSlim represents callbacks using its own type that
// implements IThreadPoolWorkItem.
//
// If we decide to expose some of the workstealing
// stuff, this is NOT the thing we want to expose to the public.
//
internal interface IThreadPoolWorkItem
{
    [SecurityCritical]
    void ExecuteWorkItem();
    [SecurityCritical]
    void MarkAborted(ThreadAbortException tae);
}

向下一層查看裡面兩個方法

[SecurityCritical]
public void ExecuteWorkItem()
{
	m_action.Invoke(m_completingTask);
}
[SecurityCritical]
public void MarkAborted(ThreadAbortException tae)
{
	/* NOP */
}

發現 MarkAborted 為空, 跳過, 以 ExecuteWorkItem 為主

其中兩個變數 m_actionm_completingTask都是在 FinishContinuations() 中設定的, 這裡偷偷超進度說一下, 該函數會在 Task 的某階段變化時調用, 所以整個流程就是

  1. Task 的特定階段改變
  2. 觸發 FinishContinuations 會把待完成任務設置進 threadPool
  3. 此時當 Task 調用介面 IThreadPoolWorkItem 中的 ExecuteWorkItem 就會執行該任務

值得一說的是, 這並不是唯一一條 Task 設置非同步任務進 TP ,與觸發 TP 中任務的路線。

而且在此刻我們沒有真的看到 TP 的資料結構, 按照第二天的文章, 其想必也會是個 lock-free data structure 吧。

明天進度

透過閱讀 FinishContinuations 來了解以下兩個問題

  1. Task 設置任務進 TP 的路線。
  2. TP ( thread pool ) 的真實面貌

明天見!


上一篇
[Day 7] .Net WhenAll 底層(2)
下一篇
[Day 9] .Net Task 底層(2)
系列文
從C到JS的同步非同步探索30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言